#include "StdAfx.h"
#include "topicdetaildialog.h"
#include "questiondetaildialog.h"
#include "popupmenu.h"

TopicDetailDialog::TopicDetailDialog( QWidget * parent )
:   DialogBase( parent ),
    m_questionTableManager( parent, m_topic.questionVector )
{
    init();
}

TopicDetailDialog::TopicDetailDialog( QWidget * parent, const Topic & topic )
:   DialogBase( parent ),
    m_topic( topic ),
    m_topicOld( topic ),
    m_questionTableManager( parent, m_topic.questionVector )
{
    init();
    updateDialog();
}

TopicDetailDialog::~TopicDetailDialog()
{
    ui.questionTableView->saveHeaderViewState( "QuestionDialogHeader" );
}

void TopicDetailDialog::init()
{
    connect( ui.questionTableView->selectionModel(), SIGNAL( selectionChanged ( const QItemSelection &, const QItemSelection & ) ), this, SLOT( onSelectionChanged ( const QItemSelection &, const QItemSelection & ) ) );
    connect( ui.topicNameLineEdit, SIGNAL( textChanged( const QString & ) ), this, SLOT( onTopicNameLineEditTextChanged( const QString & ) ) );
    connect( ui.bibleCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onBibleCheckBoxToStateChanged( bool ) ) );
    connect( ui.teoCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onTeoCheckBoxStateChanged( bool ) ) );
    connect( ui.scientificCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onScientificCheckBoxStateChanged( bool ) ) );
    connect( ui.humanCheckBox, SIGNAL( clicked( bool ) ), this, SLOT( onHumanCheckBoxStateChanged( bool ) ) );
    connect( ui.addPushButton, SIGNAL( clicked() ), this, SLOT( onAdd() ) );
    connect( ui.modifyPushButton, SIGNAL( clicked() ), this, SLOT( onUpdate() ) );
    connect( ui.deletePushButton, SIGNAL( clicked() ), this, SLOT( onRemove() ) );
    connect( ui.questionTableView, SIGNAL( contextMenu( const QPoint &, const QModelIndex & ) ), this, SLOT( onQuestionTableViewContextMenu( const QPoint &, const QModelIndex & ) ) );
    connect( ui.questionTableView, SIGNAL( doubleClicked ( const QModelIndex & ) ), SLOT( onQuestionTableViewDoubleClicked( const QModelIndex & ) ) );
    connect( ui.okPushButton, SIGNAL( clicked() ), this, SLOT( accept() ) );
    connect( ui.cancelPushButton, SIGNAL( clicked() ), this, SLOT( reject() ) );

    if (! m_questionTableManager.select( "", * ui.questionTableView ))
    {
        QMetaObject::invokeMethod( this, "close", Qt::QueuedConnection );
        return;
    }

    ui.questionTableView->init();
    ui.questionTableView->setModel( & m_questionTableManager.sortModel() );
    ui.questionTableView->restoreHeaderViewState( "QuestionDialogHeader" );
}

const Topic & TopicDetailDialog::topic() const
{
    return m_topic;
}

void TopicDetailDialog::updateDialog()
{
    ui.topicNameLineEdit->setText( m_topic.name );
    ui.bibleCheckBox->setChecked( isFlag( m_topic.category, TopicCategory::Bible ) );
    ui.teoCheckBox->setChecked( isFlag( m_topic.category, TopicCategory::Teo ) );
    ui.scientificCheckBox->setChecked( isFlag( m_topic.category, TopicCategory::Scientific ) );
    ui.humanCheckBox->setChecked( isFlag( m_topic.category, TopicCategory::Humanitarian ) );
}

void TopicDetailDialog::enableTopicCategory( TopicCategory::Enum topicCategory, bool enable )
{
     if (enable)
        setFlag( m_topic.category, topicCategory );
    else
        clearFlag( m_topic.category, topicCategory );
}

void TopicDetailDialog::enableSavePushButton()
{
    bool saveEnabled = ( 
        ! m_topic.name.isEmpty() &&
        m_topic != m_topicOld );

    ui.okPushButton->setEnabled( saveEnabled );
}

void TopicDetailDialog::onTopicNameLineEditTextChanged( const QString & text )
{
    m_topic.name = text;
    enableSavePushButton();
}

void TopicDetailDialog::onBibleCheckBoxToStateChanged( bool checked )
{
    enableTopicCategory( TopicCategory::Bible, checked );
    enableSavePushButton();
}

void TopicDetailDialog::onTeoCheckBoxStateChanged( bool checked )
{
    enableTopicCategory( TopicCategory::Teo, checked );
    enableSavePushButton();
}

void TopicDetailDialog::onScientificCheckBoxStateChanged( bool checked )
{
    enableTopicCategory( TopicCategory::Scientific, checked );
    enableSavePushButton();
}

void TopicDetailDialog::onHumanCheckBoxStateChanged( bool checked )
{
    enableTopicCategory( TopicCategory::Humanitarian, checked );
    enableSavePushButton();
}

void TopicDetailDialog::onSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected )
{
    QModelIndexList indexes = selected.indexes();
    bool selectedIndex = ! indexes.isEmpty();

    ui.modifyPushButton->setEnabled( selectedIndex );
    ui.deletePushButton->setEnabled( selectedIndex );
}

void TopicDetailDialog::onAdd()
{
    add();
}

void TopicDetailDialog::onUpdate()
{
    int standardModelRow;
    const QStandardItem * item;
    if (m_questionTableManager.getStandardModelRowAndStandardItemFromProxyIndex( ui.questionTableView->selectionModel(), standardModelRow, item ))
    {
        update( standardModelRow, item->data( Qt::UserRole + 1 ).toLongLong() );
    }
}

void TopicDetailDialog::onRemove()
{
    int standardModelRow;
    const QStandardItem * item;
    if (m_questionTableManager.getStandardModelRowAndStandardItemFromProxyIndex( ui.questionTableView->selectionModel(), standardModelRow, item ))
    {
        remove( standardModelRow, item->data( Qt::UserRole + 1 ).toLongLong() );
    }
}

void TopicDetailDialog::onQuestionTableViewContextMenu( const QPoint & point, const QModelIndex & modelIndex )
{
    PopupMenu popupMenu( this );

    int standardModelRow;
    const QStandardItem * item;
    m_questionTableManager.getStandardModelRowAndStandardItemFromProxyIndex( modelIndex, standardModelRow, item );

    ManagerBase::ActionStructVector actionStructVector;
    popupMenu.addItem( QObject::tr( "Add" ), ManagerBase::ActionBase::New ); 
    if (item != NULL)
    {
        popupMenu.addItem( QObject::tr( "Update" ), ManagerBase::ActionBase::Update );
        popupMenu.addItem( QObject::tr( "Delete" ), ManagerBase::ActionBase::Delete );
    }

    QVariant varData = popupMenu.execAndSelectData( point );
    if (! varData.isValid())
        return;

    switch ((ManagerBase::ActionBase::Enum)varData.toInt())
    {
    case ManagerBase::ActionBase::New:
        add();
        break;

    case ManagerBase::ActionBase::Update:
        update( standardModelRow, item->data( Qt::UserRole + 1 ).toLongLong() );
        break;

    case ManagerBase::ActionBase::Delete:
        remove( standardModelRow, item->data( Qt::UserRole + 1 ).toLongLong() );
        break;
    }
}

void TopicDetailDialog::onQuestionTableViewDoubleClicked( const QModelIndex & modelIndex )
{
    int standardModelRow;
    const QStandardItem * item;
    if (m_questionTableManager.getStandardModelRowAndStandardItemFromProxyIndex( modelIndex, standardModelRow, item ))
    {
        update( standardModelRow, item->data( Qt::UserRole + 1 ).toLongLong() );
    }
}

bool TopicDetailDialog::getQuestion( const qint64 & id, Question & question ) const
{
    QVector<Question>::const_iterator it;
    FOREACH (it, m_topic.questionVector)
    {
        if (it->id == id)
        {
            question = * it;
            return true;
        }
    }

    return false;
}

void TopicDetailDialog::add()
{
    QuestionDetailDialog questionDetailDialog( this );
    if (questionDetailDialog.exec() == QDialog::Accepted)
    {
        const Question & newQuestion = questionDetailDialog.question();
        m_topic.questionVector.push_back( newQuestion );
        int rowCount = m_topic.questionVector.count() - 1;
        m_questionTableManager.updateModel( rowCount, newQuestion );
        m_questionTableManager.selectRow( rowCount );
        enableSavePushButton();
    }
}

void TopicDetailDialog::update( int row, const qint64 & id )
{
    Question question;
    if (! getQuestion( id, question ))
        return;
    
    QuestionDetailDialog questionDetailDialog( this, question );
    if (questionDetailDialog.exec() != QDialog::Accepted)
        return;

    QVector<Question>::iterator it;
    FOREACH (it, m_topic.questionVector)
    {
        if (it->id == id)
        {
            * it = questionDetailDialog.question();
            break;
        }
    }

    m_questionTableManager.updateModel( row, * it );
    enableSavePushButton();
}

void TopicDetailDialog::remove( int row, const qint64 & id )
{
    if (questionBox( QObject::tr( "Delete question ?" ), QObject::tr( "Do you really want to delete selected question ?" ) ))
    {
        QVector<Question>::iterator it;
        FOREACH (it, m_topic.questionVector)
        {
            if (it->id == id)
            {
                m_topic.questionVector.erase( it );
                break;
            }
        }

        m_questionTableManager.tableModelBase().removeRows( row, 1 );
    }
}
